﻿using Serilog;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TMI85303.UI.View;
using TMI85303.UI.ViewModels;


namespace TMI85303.UI.UserControls
{
    /// <summary>
    /// SpeedConfigControl.xaml 的交互逻辑
    /// </summary>
    public partial class SpeedConfigControl : System.Windows.Controls.UserControl
    {
        private readonly Register registerIns;
        //public int none_on_off;//不知道用来干嘛
        //private bool InputDutyGreaterThanMaxDutyClamp_MaxDutyClamp = true;//本来是一个RadioButton按钮的选中值，但是没咋用，暂时这样
        public SpeedConfigControl()
        {
            InitializeComponent();
            
            var regInst = RegisterManager.Instance;
            regInst.Register.SpeedCurveUpdate += () => SpeedCurve?.Refresh();
            //regInst.Register.DrawableSurface = DrawingCanvas;//同时把绘图的实例注入到模型的接口中
            DataContext = regInst.Register;
            registerIns = regInst.Register;
        }

        private void SpeedCurve_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            registerIns.none_on_off = 0;
            registerIns.setDCoff();

            int num = 0;
            int num2 = 0;
            int num3 = 0;
            int num4 = 0;
            int num5 = 0;
            if (registerIns.Reg84_Bit2 == 1)
            {
                registerIns.ChartYAxisMax = "8160";
                num = 8160;
                num2 = 0;
                num3 = 8160;
                num4 = 0;
                num5 = num;
            }
            else if (registerIns.Reg82_Bit0 == 0)
            {
                registerIns.ChartYAxisMax = "Max";
                num = 1000;
                num2 = 0;
                num3 = 1000;
                num4 = 0;
                num5 = num;
            }
            else
            {
                num = registerIns.MaxSpeed;
                num2 = registerIns.Reg81_Bit11_Bit0;
                num3 = registerIns.MaxSpeed2;
                num4 = registerIns.Reg88_Bit11_Bit0;
                num5 = num;
                if (registerIns.Reg84_Bit3 == 1 && num3 > num5)
                {
                    num5 = num3;
                }
                registerIns.ChartYAxisMax = num5.ToString();
            }

            checked
            {
                #region slope  斜率 灰色  全部是画斜率
                if (registerIns.Reg84_Bit2 == 1) // STAIR_EN == ENABLE
                {
                    Graphics g = e.Graphics;
                    //slope  斜率 灰色  全部是画斜率  阶梯 25
                    drawLine(ref g, (float)((double)(registerIns.Reg84_Bit14_Bit9 * 8 + 7) / 511.0), (float)((double)registerIns.Reg86_Bit15_Bit8 / (double)registerIns.Reg86_Bit15_Bit8Max), 1f, (float)((double)registerIns.Reg86_Bit15_Bit8 / (double)registerIns.Reg86_Bit15_Bit8Max));
                    g = e.Graphics;
                    drawLine(ref g, (float)((double)(registerIns.Reg87_Bit13_Bit8 * 8 + 7) / 511.0), (float)((double)registerIns.Reg86_Bit7_Bit0 / (double)registerIns.Reg86_Bit7_Bit0Max), (float)((double)(registerIns.Reg84_Bit14_Bit9 * 8 + 7) / 511.0), (float)((double)registerIns.Reg86_Bit7_Bit0 / (double)registerIns.Reg86_Bit7_Bit0Max));
                    g = e.Graphics;
                    drawLine(ref g, (float)((double)(registerIns.Reg87_Bit5_Bit0 * 8 + 7) / 511.0), (float)((double)registerIns.Reg85_Bit15_Bit8 / (double)registerIns.Reg85_Bit15_Bit8Max), (float)((double)(registerIns.Reg87_Bit13_Bit8 * 8 + 7) / 511.0), (float)((double)registerIns.Reg85_Bit15_Bit8 / (double)registerIns.Reg85_Bit15_Bit8Max));
                    g = e.Graphics;
                    drawLine(ref g, 0f, (float)((double)registerIns.Reg85_Bit7_Bit0 / (double)registerIns.Reg85_Bit7_Bit0Max), (float)((double)(registerIns.Reg87_Bit5_Bit0 * 8 + 7) / 511.0), (float)((double)registerIns.Reg85_Bit7_Bit0 / (double)registerIns.Reg85_Bit7_Bit0Max));
                    g = e.Graphics;
                    drawLine(ref g, (float)((double)(registerIns.Reg84_Bit14_Bit9 * 8 + 7) / 511.0), (float)((double)registerIns.Reg86_Bit15_Bit8 / (double)registerIns.Reg86_Bit15_Bit8Max), (float)((double)(registerIns.Reg84_Bit14_Bit9 * 8 + 7) / 511.0), (float)((double)registerIns.Reg86_Bit7_Bit0 / (double)registerIns.Reg86_Bit7_Bit0Max));
                    g = e.Graphics;
                    drawLine(ref g, (float)((double)(registerIns.Reg87_Bit13_Bit8 * 8 + 7) / 511.0), (float)((double)registerIns.Reg86_Bit7_Bit0 / (double)registerIns.Reg86_Bit7_Bit0Max), (float)((double)(registerIns.Reg87_Bit13_Bit8 * 8 + 7) / 511.0), (float)((double)registerIns.Reg85_Bit15_Bit8 / (double)registerIns.Reg85_Bit15_Bit8Max));
                    g = e.Graphics;
                    drawLine(ref g, (float)((double)(registerIns.Reg87_Bit5_Bit0 * 8 + 7) / 511.0), (float)((double)registerIns.Reg85_Bit15_Bit8 / (double)registerIns.Reg85_Bit15_Bit8Max), (float)((double)(registerIns.Reg87_Bit5_Bit0 * 8 + 7) / 511.0), (float)((double)registerIns.Reg85_Bit7_Bit0 / (double)registerIns.Reg85_Bit7_Bit0Max));
                }
                else if (registerIns.Reg84_Bit3 == 1) //DIR50 = ENABLE
                {
                    //slope  斜率 灰色  全部是画斜率 V型
                    Graphics g = e.Graphics;
                    drawLine(ref g, 0f, (float)((double)num3 / (double)num5), 0.5f, (float)((double)num4 / (double)num5));
                    g = e.Graphics;
                    drawLine(ref g, 0.5f, (float)((double)num2 / (double)num5), 1f, (float)((double)num / (double)num5));
                    g = e.Graphics;
                    drawLine(ref g, 0.5f, (float)((double)num2 / (double)num5), 0.5f, (float)((double)num4 / (double)num5));
                }
                else if ((registerIns.Reg90_Bit13_Bit6 == 0) | registerIns.Reg82_Bit0 == 0) // SLPSWDTY == 0 | SPD_CL_EN == OPENLOOP
                {
                    Graphics g = e.Graphics;
                    drawLine(ref g, 0f, (float)((double)num2 / (double)num), 1f, 1f);
                }
                else
                {
                    Graphics g = e.Graphics;
                    drawLine(ref g, 0f, (float)((double)num2 / (double)num), (float)((double)registerIns.Reg90_Bit13_Bit6 / 255.0), (float)((double)registerIns.Reg91 / (double)num));
                    g = e.Graphics;
                    drawLine(ref g, (float)((double)registerIns.Reg90_Bit13_Bit6 / 255.0), (float)((double)registerIns.Reg91 / (double)num), 1f, 1f);
                }
                #endregion

                //CMD_ON 垂直线 蓝色
                if (registerIns.Reg76_Bit7_Bit0 > 0) //CMD_ON > 0
                {
                    if (registerIns.Reg84_Bit3 == 1) //DIR50 = ENABLE
                    {
                        //CMD_ON 垂直线 蓝色 和三角形
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)(0.5 - 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), 0f, (float)(0.5 - 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), 1f, 1);
                        g = e.Graphics;
                        drawLine(ref g, (float)(0.5 + 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), 0f, (float)(0.5 + 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), 1f, 1);
                        g = e.Graphics;
                        drawTriangle(ref g, (float)(0.5 + 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), py: true);
                        g = e.Graphics;
                        drawTriangle(ref g, (float)(0.5 - 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), py: true);
                    }
                    else
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)(1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), 0f, (float)(1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), 1f, 1);
                        g = e.Graphics;
                        drawTriangle(ref g, (float)(1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0), py: true);
                    }
                }

                // CMD_ONHYS 垂直线 番茄色
                if (registerIns.DC_off > 0.0)
                {
                    if (registerIns.Reg84_Bit3 == 1)//DIR50 = ENABLE
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)(0.5 - registerIns.DC_off), 0f, (float)(0.5 - registerIns.DC_off), 1f, 3);
                        g = e.Graphics;
                        drawLine(ref g, (float)(0.5 + registerIns.DC_off), 0f, (float)(0.5 + registerIns.DC_off), 1f, 3);
                        g = e.Graphics;
                        drawTriangle(ref g, (float)(0.5 + registerIns.DC_off), py: false);
                        g = e.Graphics;
                        drawTriangle(ref g, (float)(0.5 - registerIns.DC_off), py: false);
                    }
                    else
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)registerIns.DC_off, 0f, (float)registerIns.DC_off, 1f, 3);
                        g = e.Graphics;
                        drawTriangle(ref g, (float)registerIns.DC_off, py: false);
                    }
                }


                // CMD_ONHYS 垂直线 番茄色
                if (registerIns.Reg84_Bit3 == 0) //DIR50 = DISABLE
                {
                    double num6 = 1.0 - (double)(registerIns.Reg72_Bit13_Bit10 - 1) * 0.0156;
                    if (registerIns.Reg84_Bit3 == 1) //DIR50 = ENABLE
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)num6, 0f, (float)num6, 1f, 3);
                        g = e.Graphics;
                        drawLine(ref g, (float)(1.0 - num6), 0f, (float)(1.0 - num6), 1f, 3);
                    }
                    else
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)num6, 0f, (float)num6, 1f, 3);
                    }
                }

                // MAX_DTYCLP 垂直线水平直线 洋红色
                if ((registerIns.Reg72_Bit3_Bit0 > 0) & registerIns.Reg82_Bit0 != 0) // MAX_DTYCLP > 0 & SPD_CL_EN == OPENLOOP
                {
                    double num7 = 0.01 * (800.0 * (double)registerIns.Reg72_Bit3_Bit0 / 511.0);
                    if (registerIns.Reg84_Bit3 == 1)
                    {
                        Graphics g = e.Graphics;
                        // MAX_DTYCLP 垂直线 洋红色
                        drawLine(ref g, (float)(1.0 - num7), 0f, (float)(1.0 - num7), 1f, 2);
                        g = e.Graphics;
                        drawLine(ref g, (float)num7, 0f, (float)num7, 1f, 2);

                        //MAX_DTYCLP 水平线 洋红色
                        if (registerIns.InputDutyGreaterThanMaxDutyClamp_MaxDutyClamp)
                        {
                            g = e.Graphics;
                            drawLine(ref g, (float)(1.0 - num7), (float)registerIns.getYpoint(1.0 - num7), 1f, (float)registerIns.getYpoint(1.0 - num7), 6);
                            g = e.Graphics;
                            drawLine(ref g, 0f, (float)registerIns.getYpoint(num7), (float)num7, (float)registerIns.getYpoint(num7), 6);
                        }
                        else
                        {
                            g = e.Graphics;
                            drawLine(ref g, (float)(1.0 - num7), (float)(1.0 - 2.0 * num7), 1f, 1f, 6);
                            g = e.Graphics;
                            drawLine(ref g, (float)num7, (float)(1.0 - 2.0 * num7), 0f, 1f, 6);
                        }
                    }
                    else
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)(1.0 - num7), 0f, (float)(1.0 - num7), 1f, 2); //MAX_DTYCLP 垂直线 洋红色

                        //MAX_DTYCLP 水平线 洋红色
                        if (registerIns.InputDutyGreaterThanMaxDutyClamp_MaxDutyClamp)
                        {
                            g = e.Graphics;
                            drawLine(ref g, (float)(1.0 - num7), (float)registerIns.getYpoint(1.0 - num7), 1f, (float)registerIns.getYpoint(1.0 - num7), 6);
                        }
                        else
                        {
                            g = e.Graphics;
                            drawLine(ref g, (float)(1.0 - num7), (float)(1.0 - num7), 1f, 1f, 6);
                        }
                    }
                }

                // 画MIN_DTYCLP 垂直和水平线 绿色
                if (registerIns.Reg72_Bit9_Bit4 > 0) //MIN_DTYCLP > 0
                {
                    double num8 = (double)(registerIns.Reg72_Bit9_Bit4 * 4) / 511.0;
                    if (registerIns.Reg84_Bit3 == 1) // DIR50 = ENABLE
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)(0.5 + num8), 0f, (float)(0.5 + num8), 1f, 5);//MIN_DTYCLP 垂直线 绿色
                        g = e.Graphics;
                        drawLine(ref g, 0.5f, (float)registerIns.getYpoint(0.5 + num8), (float)(0.5 + num8), (float)registerIns.getYpoint(0.5 + num8), 4);//MIN_DTYCLP 水平线 绿色
                    }
                    else
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)num8, 0f, (float)num8, 1f, 5);//MIN_DTYCLP 垂直线 绿色
                        g = e.Graphics;
                        drawLine(ref g, 0f, (float)registerIns.getYpoint(num8), (float)num8, (float)registerIns.getYpoint(num8), 4);//MIN_DTYCLP 水平线 绿色
                    }
                }


                // MIN_DTYCLP2 垂直和水平线 绿色
                if (registerIns.Reg90_Bit5_Bit0 > 0) //MIN_DTYCLP2 > 0
                {
                    double num9 = (double)(registerIns.Reg90_Bit5_Bit0 * 4) / 511.0;
                    if (registerIns.Reg84_Bit3 == 1) // DIR50 = ENABLE
                    {
                        Graphics g = e.Graphics;
                        drawLine(ref g, (float)(0.5 - num9), 0f, (float)(0.5 - num9), 1f, 5); //MIN_DTYCLP 垂直线 绿色
                        g = e.Graphics;
                        drawLine(ref g, (float)(0.5 - num9), (float)registerIns.getYpoint(0.5 - num9), 0.5f, (float)registerIns.getYpoint(0.5 - num9), 4); //MIN_DTYCLP 水平线 绿色
                    }
                }


                int num10 = MainWindowVM.MainDutyCycleValue;
                if (!MainWindowVM.MainIsRunn)
                {
                    num10 = (registerIns.Reg84_Bit3 == 1 ? ((int)Math.Round((double)MainWindowVM.MainDutyCycleValueMax / 2.0)) : ((registerIns.Reg84_Bit0 != 0) ? MainWindowVM.MainDutyCycleValueMax : 0));
                }
                if (registerIns.Reg84_Bit0 == 1)
                {
                    num10 = MainWindowVM.MainDutyCycleValueMax - num10;
                }

                //画点
                if (num > num2)
                {
                    if (registerIns.getYpoint((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax) < 0.0)
                    {
                        Graphics g = e.Graphics;
                        drawPoint(ref g, (float)((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax), (float)(0.0 - registerIns.getYpoint((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax, isSinglePoint: true)));
                    }
                    else
                    {
                        Graphics g = e.Graphics;
                        drawPoint(ref g, (float)((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax), (float)registerIns.getYpoint((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax, isSinglePoint: true));
                    }
                }

                //计算none_on_off等于 0 1 2
                if ((registerIns.Reg76_Bit7_Bit0 == 0) & (registerIns.DC_off == 0.0))
                {
                    registerIns.none_on_off = 0;
                }
                else
                {
                    bool flag;
                    bool flag2;
                    if (registerIns.Reg84_Bit3 == 1)
                    {
                        flag = (((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax > 0.5 + 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0) | ((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax < 0.5 - 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0));
                        flag2 = (((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax < 0.5 + registerIns.DC_off) & ((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax > 0.5 - registerIns.DC_off));
                    }
                    else
                    {
                        flag = ((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax > 1.0 * (double)(registerIns.Reg76_Bit7_Bit0 * 2) / 511.0);
                        flag2 = ((double)num10 / (double)MainWindowVM.MainDutyCycleValueMax < registerIns.DC_off);
                    }
                    if (((registerIns.none_on_off == 2) | (registerIns.none_on_off == 0)) && flag)
                    {
                        registerIns.none_on_off = 1;
                    }
                    if (((registerIns.none_on_off == 1) | (registerIns.none_on_off == 0)) && flag2)
                    {
                        registerIns.none_on_off = 2;
                    }
                }

                /*
                if ((getYpoint((double)num10 / (double)trackBar_Speed.Maximum) < 0.0) | radioButton_reg82_bit0_0.Checked)
                {
                    //Label242.Visible = true;
                }
                else
                {
                    //Label242.Visible = false;
                }


                if (none_on_off > 0)
                {
                    if (radioButton_reg84_bit3_0.Checked & ((double)num10 / (double)trackBar_Speed.Maximum > 1.0 - (double)(registerIns.Reg72_Bit13_Bit10 - 1) * 0.0156))
                    {
                        //Label243.Text = "OFF";
                        //Label243.ForeColor = Color.Red;
                    }
                    else if (none_on_off == 2)
                    {
                        //Label243.Text = "OFF";
                        //Label243.ForeColor = Color.Red;
                    }
                    else if (none_on_off == 1)
                    {
                        //Label243.Text = "ON";
                        //Label243.ForeColor = Color.Green;
                    }
                    //if (!Label243.Visible)
                    //{
                    //    Label243.Visible = true;
                    //}
                }
                else
                {
                    //Label243.Visible = false;
                }*/


            }
        }

        /// <summary>
        /// 画三角形
        /// </summary>
        /// <param name="g"></param>
        /// <param name="px"> 三角形顶点的X坐标</param>
        /// <param name="py">三角形是向上还是向下指，true向上，False向下</param>
        private void drawTriangle(ref Graphics g, float px, bool py)
        {
            System.Drawing.Pen pen = new(System.Drawing.Color.Tomato, 3f);//dcoff
            System.Drawing.Pen pen2 = new(System.Drawing.Color.Blue, 3f);//dcon
            checked
            {
                int num = SpeedCurve.Size.Height - 3;
                int num2 = SpeedCurve.Size.Width - 3;
                px *= (float)num2;
                if (registerIns.Reg84_Bit0 == 1) //CMD_INV == INVERT
                {
                    px = (float)SpeedCurve.Size.Width - px - 3f;
                }
                if (py) //向上
                {
                    System.Drawing.Point[] points = new System.Drawing.Point[3]
                    {
                        new((int)Math.Round(px - 1f), num - 3),
                        new((int)Math.Round(px + 1f), num - 3),
                        new((int)Math.Round(px), num - 3 - 1)
                    };
                    g.DrawPolygon(pen2, points);
                }
                else //向下
                {
                    System.Drawing.Point[] points2 = new System.Drawing.Point[3]
                    {
                        new((int)Math.Round(px - 1f), num - 3 - 1),
                        new((int)Math.Round(px + 1f), num - 3 - 1),
                        new((int)Math.Round(px), num - 3)
                    };
                    g.DrawPolygon(pen, points2);
                }
                pen2.Dispose();
                pen.Dispose();
            }
        }

        private void drawLine(ref Graphics g, float x1, float y1, float x2, float y2, int lineColor = 0)
        {
            System.Drawing.Pen pen = lineColor switch
            {
                0 => new(System.Drawing.Color.LightSlateGray, 2f), //slope  斜率 灰色
                1 => new(System.Drawing.Color.Blue, 1f), //dcon CMD_ON 垂直线 蓝色
                2 => new(System.Drawing.Color.Magenta, 1f), //max  MAX_DTYCLP 垂直线 洋红色
                3 => new(System.Drawing.Color.Tomato, 1f), //dcoff CMD_ONHYS 垂直线 番茄色
                4 => new(System.Drawing.Color.Green, 3f), //min  MIN_DTYCLP 水平线 绿色
                5 => new(System.Drawing.Color.Green, 1f), //min MIN_DTYCLP 垂直线 绿色
                6 => new(System.Drawing.Color.Magenta, 3f), //max MAX_DTYCLP 水平线 洋红色
                _ => new(System.Drawing.Color.LightSlateGray, 2f), //slope  斜率 灰色,
            };

            checked
            {
                int num = SpeedCurve.Size.Height - 3;
                int num2 = SpeedCurve.Size.Width - 3;
                y1 = (float)num - y1 * (float)num;
                y2 = (float)num - y2 * (float)num;
                x1 *= (float)num2;
                x2 *= (float)num2;
                if (registerIns.Reg84_Bit0 == 1)
                {
                    x1 = (float)SpeedCurve.Size.Width - x1 - 3f;
                    x2 = (float)SpeedCurve.Size.Width - x2 - 3f;
                }
                g.DrawLine(pen, x1, y1, x2, y2);
                pen.Dispose();
            }
        }

        private void drawPoint(ref Graphics g, float px, float py)
        {
            System.Drawing.Pen pen = new(System.Drawing.Color.Red, 5f);
            checked
            {
                int num = SpeedCurve.Size.Height - 3;
                int num2 = SpeedCurve.Size.Width - 3;
                py = (float)num - py * (float)num;
                px *= (float)num2;
                if (registerIns.Reg84_Bit0 == 1)
                {
                    px = (float)SpeedCurve.Size.Width - px - 3f;
                }
            }
            try
            {
                // 检查 px, py 等浮点数值的合理性
                if (float.IsInfinity(px) || float.IsNaN(px) || float.IsInfinity(py) || float.IsNaN(py))
                {
                    throw new Exception("计算结果不合理。");
                }

                g.DrawEllipse(pen, px - 1f, py - 1f, 2f, 2f);
            }
            catch (Exception ex)
            {
                Log.Information($"发生异常: {ex.Message}");
            }
            finally
            {
                pen.Dispose();
            }

        }


    }
}
